package scatter.comment.rest.star.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.Assert;
import scatter.comment.pojo.star.param.CommentStarAddStarParam;
import scatter.comment.pojo.star.param.CommentStarCancelStarParam;
import scatter.comment.pojo.star.po.CommentStar;
import scatter.comment.pojo.star.po.CommentStar;
import scatter.comment.rest.componentext.CommentStarOnAddOrCancelListener;
import scatter.comment.rest.star.mapstruct.CommentStarMapStruct;
import scatter.comment.rest.star.mapper.CommentStarMapper;
import scatter.comment.rest.star.service.ICommentStarService;
import scatter.common.pojo.form.BasePageQueryForm;
import scatter.common.rest.service.IBaseAddUpdateQueryFormServiceImpl;
import org.springframework.stereotype.Service;
import scatter.comment.pojo.star.form.CommentStarAddForm;
import scatter.comment.pojo.star.form.CommentStarUpdateForm;
import scatter.comment.pojo.star.form.CommentStarPageQueryForm;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

/**
 * <p>
 * 主体点赞表 服务实现类
 * </p>
 *
 * @author yw
 * @since 2021-11-04
 */
@Slf4j
@Service
@Transactional
public class CommentStarServiceImpl extends IBaseAddUpdateQueryFormServiceImpl<CommentStarMapper, CommentStar, CommentStarAddForm, CommentStarUpdateForm, CommentStarPageQueryForm> implements ICommentStarService {


    @Qualifier("commonDbTaskExecutor")
    @Autowired
    private ExecutorService executorService;

    @Autowired(required = false)
    private List<CommentStarOnAddOrCancelListener> commentStarOnAddOrCancelListenerList;


    @Override
    public void preAdd(CommentStarAddForm addForm,CommentStar po) {
        super.preAdd(addForm,po);

    }

    @Override
    public void preUpdate(CommentStarUpdateForm updateForm,CommentStar po) {
        super.preUpdate(updateForm,po);

    }


    /**
     * 异步处理添加，该方法永远返回true
     * @param addStartParam
     * @return
     */
    @Override
    public CommentStar addStar(CommentStarAddStarParam addStartParam) {
        CommentStar commentSubjectStar = CommentStarMapStruct.INSTANCE.addStartParamToPo(addStartParam);
        commentSubjectStar.setTimeAt(LocalDateTime.now());
        // 楼层默认设置为1
        commentSubjectStar.setFloor(Optional.ofNullable(addStartParam.getFloor()).orElse(1));
        log.info("开始添加一个点赞,subjectId={},userId={}",addStartParam.getSubjectId(),addStartParam.getOwnerUserId());
        boolean save = save(commentSubjectStar);
        log.info("添加一个点赞结束,subjectId={},userId={},id={}",addStartParam.getSubjectId(),addStartParam.getOwnerUserId(),commentSubjectStar.getId());
        if (!isEmpty(commentStarOnAddOrCancelListenerList)) {
            for (CommentStarOnAddOrCancelListener commentStarOnAddListener : commentStarOnAddOrCancelListenerList) {
                commentStarOnAddListener.onCommentStarAdd(addStartParam,commentSubjectStar);
            }
        }
        return commentSubjectStar;
    }

    /**
     * 异步处理取消，该方法永远返回 true
     * @param cancelStarParam
     * @return
     */
    @Override
    public boolean cancelStar(CommentStarCancelStarParam cancelStarParam) {
        executorService.execute(()->{
            log.info("开始取消点赞,subjectId={},userId={}",cancelStarParam.getSubjectId(),cancelStarParam.getOwnerUserId());
            LambdaQueryWrapper<CommentStar> starLambdaQueryWrapper = Wrappers.<CommentStar>lambdaQuery()
                    .eq(CommentStar::getSubjectId, cancelStarParam.getSubjectId())
                    .eq(CommentStar::getOwnerUserId, cancelStarParam.getOwnerUserId())
                    .eq(!isStrEmpty(cancelStarParam.getGroupFlag()), CommentStar::getGroupFlag, cancelStarParam.getGroupFlag() );

            boolean remove = remove(starLambdaQueryWrapper);


            if (!isEmpty(commentStarOnAddOrCancelListenerList)) {
                for (CommentStarOnAddOrCancelListener commentStarOnAddListener : commentStarOnAddOrCancelListenerList) {
                    commentStarOnAddListener.onCommentStarCancel(cancelStarParam);
                }
            }

            log.info("取消点赞结束,subjectId={},userId={}",cancelStarParam.getSubjectId(),cancelStarParam.getOwnerUserId());
        });
        return true;
    }

    @Override
    public Map<String, Page<CommentStar>> listLatestStarForPerSubject(List<String> subjectIds, Integer count, String groupFlag) {
        Assert.notEmpty(subjectIds,"subjectIds 不能为空");
        Assert.notNull(count,"count 不能为空");


        Map<String,Page<CommentStar>> result = new HashMap<>();

        CompletableFuture[] completableFutures = subjectIds.stream().map(subjectId -> CompletableFuture.supplyAsync(() -> {
            // 我嚓，这个 page 不能提出来，否则得到的数据会是一样的
            Page page = convertPage(new BasePageQueryForm().setCurrent(1L).setSize(Integer.toUnsignedLong(count)));
            page.setSearchCount(false);
            Page<CommentStar> page1 = page(page, Wrappers.<CommentStar>lambdaQuery()
                    .eq(CommentStar::getSubjectId, subjectId)
                    .eq(!isStrEmpty(groupFlag), CommentStar::getGroupFlag, groupFlag)
                    .orderByDesc(CommentStar::getTimeAt));
            return page1;
        }, executorService).whenComplete((r,e)->{result.put(subjectId, (Page<CommentStar>)r);})).toArray(CompletableFuture[]::new);
        CompletableFuture.allOf(completableFutures).join();
        return result;
    }

}
